﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.SimulationSpeed.CApSimulationSpeedApp
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using EngineeringInternalExtension;
using Microsoft.Win32;
using System;
using System.Runtime.InteropServices;
using System.Threading;
using Tecnomatix.Engineering;


namespace DnProcessSimulateCommands.SimulationSpeed;

internal class CApSimulationSpeedApp
{
  private bool m_isSimulationRunning;
  private int m_lastTime;
  private int m_timeInterval;
  private int m_playbackMaxSpeed;
  private const int PLAYBACK_MAX_SPEED = 1500;
  private int m_accumulatedTime;
  private const int THREAD_SLEEP_THRESHOLD_TIME = 16 /*0x10*/;

  [DllImport("UiTasks.dll")]
  private static extern void SetSimulationSlowestSpeedInterval(int timeMs);

  public void Run()
  {
    this.InitVariables();
    TxApplication.DocumentCollection.DocumentLoaded += new TxDocumentCollection_DocumentLoadedEventHandler(this.DocumentCollection_DocumentLoaded);
    if (TxApplication.ActiveDocument == null || TxApplication.ActiveDocument.CurrentStudy == null)
      return;
    this.RegisterToSimulationEvents();
  }

  private void SimulationPlayer_TimeIntervalReached(
    object sender,
    TxSimulationPlayer_TimeIntervalReachedEventArgs args)
  {
    this.OnTimeInterval(args.CurrentTime);
  }

  private void SimulationPlayer_SimulationStartedForward(
    object sender,
    TxSimulationPlayer_SimulationStartedForwardEventArgs args)
  {
    this.InitVariables();
  }

  private void SimulationPlayer_SimulationStartedBackward(
    object sender,
    TxSimulationPlayer_SimulationStartedBackwardEventArgs args)
  {
    this.InitVariables();
  }

  private void SimulationPlayer_SimulationStopped(
    object sender,
    TxSimulationPlayer_SimulationStoppedEventArgs args)
  {
    this.m_isSimulationRunning = false;
  }

  private void DocumentCollection_DocumentLoaded(
    object sender,
    TxDocumentCollection_DocumentLoadedEventArgs args)
  {
    this.RegisterToSimulationEvents();
  }

  private void ActiveDocument_Unloading(object sender, TxDocument_UnloadingEventArgs args)
  {
    this.UnregisterFromSimulationEvents();
  }

  private void InitVariables()
  {
    this.m_isSimulationRunning = true;
    this.m_timeInterval = Convert.ToInt32(TxApplication.ActiveDocument.SimulationPlayer.TimeInterval * 1000.0);
    this.m_playbackMaxSpeed = this.CalcMaxPlaybackSpeed(this.m_timeInterval);
    this.m_lastTime = Environment.TickCount;
  }

  private int CalcMaxPlaybackSpeed(int timeInterval)
  {
    int num = 0;
    string name = TxApplicationEx.ConfigurationPath + "\\Options";
    using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(name))
    {
      object obj = registryKey.GetValue("SimulationSlowestSpeedInterval");
      num = obj == null ? 1500 : Convert.ToInt32(obj);
    }
    CApSimulationSpeedApp.SetSimulationSlowestSpeedInterval(num);
    return Math.Max(num, 2 * timeInterval);
  }

  private void OnTimeInterval(double simTime)
  {
    if (this.m_isSimulationRunning && TxApplication.ActiveDocument.SimulationPlayer.RefreshMode && !TxSimulationPlayerEx.IgnoreSimulationSpeed(TxApplication.ActiveDocument.SimulationPlayer, new bool?()))
    {
      int num1 = 100 - TxApplication.Options.Simulation.SimulationSpeed;
      int num2 = Environment.TickCount - this.m_lastTime;
      int num3 = num1 != 50 ? (num1 <= 50 ? Convert.ToInt32((double) this.m_timeInterval / 50.0 * (double) num1) - num2 : Convert.ToInt32((double) (this.m_playbackMaxSpeed - this.m_timeInterval) / 50.0 * (double) (num1 - 50)) - num2) : this.m_timeInterval - num2;
      int num4 = num3 + this.m_accumulatedTime;
      if (num4 >= 16 /*0x10*/)
      {
        int num5 = num4 % 16 /*0x10*/;
        this.m_accumulatedTime = num5;
        int millisecondsTimeout = num4 - num5;
        int tickCount = Environment.TickCount;
        Thread.Sleep(millisecondsTimeout);
        this.m_accumulatedTime -= Environment.TickCount - tickCount - millisecondsTimeout;
      }
      else if (num3 > 0)
        this.m_accumulatedTime += num3;
      else
        this.m_accumulatedTime = 0;
    }
    else
      this.m_accumulatedTime = 0;
    this.m_lastTime = Environment.TickCount;
  }

  private void RegisterToSimulationEvents()
  {
    TxApplication.ActiveDocument.SimulationPlayer.TimeIntervalReached += new TxSimulationPlayer_TimeIntervalReachedEventHandler(this.SimulationPlayer_TimeIntervalReached);
    TxApplication.ActiveDocument.SimulationPlayer.SimulationStartedForward += new TxSimulationPlayer_SimulationStartedForwardEventHandler(this.SimulationPlayer_SimulationStartedForward);
    TxApplication.ActiveDocument.SimulationPlayer.SimulationStartedBackward += new TxSimulationPlayer_SimulationStartedBackwardEventHandler(this.SimulationPlayer_SimulationStartedBackward);
    TxApplication.ActiveDocument.SimulationPlayer.SimulationStopped += new TxSimulationPlayer_SimulationStoppedEventHandler(this.SimulationPlayer_SimulationStopped);
    TxApplication.ActiveDocument.Unloading += new TxDocument_UnloadingEventHandler(this.ActiveDocument_Unloading);
  }

  private void UnregisterFromSimulationEvents()
  {
    TxApplication.ActiveDocument.Unloading -= new TxDocument_UnloadingEventHandler(this.ActiveDocument_Unloading);
    TxApplication.ActiveDocument.SimulationPlayer.TimeIntervalReached -= new TxSimulationPlayer_TimeIntervalReachedEventHandler(this.SimulationPlayer_TimeIntervalReached);
    TxApplication.ActiveDocument.SimulationPlayer.SimulationStartedForward -= new TxSimulationPlayer_SimulationStartedForwardEventHandler(this.SimulationPlayer_SimulationStartedForward);
    TxApplication.ActiveDocument.SimulationPlayer.SimulationStartedBackward -= new TxSimulationPlayer_SimulationStartedBackwardEventHandler(this.SimulationPlayer_SimulationStartedBackward);
    TxApplication.ActiveDocument.SimulationPlayer.SimulationStopped -= new TxSimulationPlayer_SimulationStoppedEventHandler(this.SimulationPlayer_SimulationStopped);
  }
}
